package com.marvels.system.permission.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.utils.ServerProperties;
import com.marvels.common.utils.StringUtils;
import com.marvels.system.permission.dao.SysRoleDao;
import com.marvels.system.permission.dao.SysUserDao;
import com.marvels.system.permission.dto.SysRoleDTO;
import com.marvels.system.permission.dto.SysRoleMenuDTO;
import com.marvels.system.permission.dto.SysUserDTO;
import com.marvels.system.permission.service.SysRoleService;
import com.marvels.system.permission.service.SysUserService;

import cn.hutool.core.util.StrUtil;


/**
 * 
* @ClassName: SysRoleService 
* @Description:  系统角色服务类
* @author 李瑶
* @date 2018年1月24日 上午10:16:09 
*
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {
	@Autowired
	private SysRoleDao sysRoleDao;
	@Autowired
	private SysUserDao sysUserDao;
	@Value("${config.properties.path}")
	private String configPropertiesPath;
	
	@Override
	public Page<SysRoleDTO> getRolePage(SysRoleDTO conditions,Integer pageNo,Integer pageSize)throws MarvelsBusinessException{
		if(pageNo <= 0){
			pageNo = 1;
		}
		if(pageSize <=0){
			pageSize = 20;
		}
		if(StringUtils.isNotEmpty(conditions.getSortBy())){
			PageHelper.orderBy(conditions.getSortBy()+" "+conditions.getSortType());
		}
		PageHelper.startPage(pageNo, pageSize);
		Page<SysRoleDTO> rolePage = sysRoleDao.selectRolePage(conditions);
		return rolePage;
	}
	
	@Override
	public int addRole(SysRoleDTO sysRole)throws MarvelsBusinessException{
		if(sysRole == null){
			throw new MarvelsBusinessException("入参为空");
		}
		if(StringUtils.isEmpty(sysRole.getRoleCode())){
			throw new MarvelsBusinessException("角色代码为空");
		}
		if(StringUtils.isEmpty(sysRole.getRoleName())){
			throw new MarvelsBusinessException("角色名称为空");
		}
		if(isRoleCodeExistence(sysRole.getRoleCode())){
			throw new MarvelsBusinessException("角色代码"+sysRole.getRoleCode()+"已存在");
		}
		sysRole.setCreatedBy(sysRole.obtainLoginUserName());
		sysRole.setUpdatedBy(sysRole.obtainLoginUserName());
		int n = 0;
		n = sysRoleDao.insert(sysRole);
		return n;
	}
	
	private boolean isRoleCodeExistence(String code){
		boolean isExisted = false;
		int count = sysRoleDao.selectCountByRoleCode(code);
		if(count > 0){
			isExisted = true;
		}
		return isExisted;
	}
	
	@Override
	public SysRoleDTO getRoleById(SysRoleDTO role)throws MarvelsBusinessException{
		isPrimaryKeyEmpty(role);
		return sysRoleDao.selectByPrimaryKey(role);
	}
	
	private void isPrimaryKeyEmpty(SysRoleDTO role) throws MarvelsBusinessException{
		if(role == null){
			throw new MarvelsBusinessException("入参为空");
		}
		Integer roleId = role.getRoleId();
		if(roleId==null || roleId<=0){
			throw new MarvelsBusinessException("角色id为空");
		}
	}
	
	@Override
	public int updateRole(SysRoleDTO sysRole)throws MarvelsBusinessException{
		isPrimaryKeyEmpty(sysRole);
		return sysRoleDao.updateByPrimaryKey(sysRole);
	}
	
	@Override
	public int deleteRole(SysRoleDTO record)throws MarvelsBusinessException{
		isPrimaryKeyEmpty(record);
		record.setUpdatedBy(record.obtainLoginUserName());
		return sysRoleDao.deleteByPrimaryKey(record);
	}

	@Override
	public List<SysRoleDTO> getAllRoles() throws MarvelsBusinessException {
		return sysRoleDao.selectAll();
	}
	
	@Override
	public int addMenuRelation(SysRoleDTO role) throws MarvelsBusinessException {
		if(role == null){
			throw new MarvelsBusinessException("入参为空");
		}
		String roleCode = role.getRoleCode();
		if(StringUtils.isEmpty(roleCode)){
			throw new MarvelsBusinessException("角色编码为空");
		}
		role.setUpdatedBy(role.obtainLoginUserName());
		
		//原有的角色菜单关系
		List<SysRoleMenuDTO> roleMenuRelations = sysRoleDao.selectRoleMenuRelations(role);
		//修改的角色菜单关系
		List<SysRoleMenuDTO> newRelations = role.getMenus();
		//待新增的角色菜单关系
		List<SysRoleMenuDTO> insertList = null;
		//待删除的角色菜单关系
		List<SysRoleMenuDTO> delList = null;
		int n = 0;
		if(CollectionUtils.isEmpty(roleMenuRelations)){
			//全部新增
			if(CollectionUtils.isNotEmpty(newRelations)){
				for(SysRoleMenuDTO rm : newRelations){
					rm.setCreatedBy(role.obtainLoginUserName());
					rm.setUpdatedBy(role.obtainLoginUserName());
				}
				n = sysRoleDao.insertRelation(newRelations);
			}
		}else if(CollectionUtils.isEmpty(newRelations)){
			//全部删除
			n = sysRoleDao.deleteRelation(role);
		}else{
			insertList = new ArrayList<SysRoleMenuDTO>();
			delList = new ArrayList<SysRoleMenuDTO>();
			//判断是否有新增的角色菜单关系
			for(SysRoleMenuDTO newRelation : newRelations){
				boolean exist = false;
				for(SysRoleMenuDTO relation : roleMenuRelations){
					if(org.apache.commons.lang.StringUtils.equals(newRelation.getMenuCode(), relation.getMenuCode())){
						exist = true;
						break;
					}
				}
				if(!exist){
					newRelation.setCreatedBy(role.obtainLoginUserName());
					newRelation.setUpdatedBy(role.obtainLoginUserName());
					insertList.add(newRelation);
				}
			}
			//判断是否有删除的角色菜单关系
			for(SysRoleMenuDTO relation : roleMenuRelations){
				boolean exist = false;
				for(SysRoleMenuDTO newRelation : newRelations){
					if(org.apache.commons.lang.StringUtils.equals(newRelation.getMenuCode(), relation.getMenuCode())){
						exist = true;
						break;
					}
				}
				if(!exist){
					relation.setCreatedBy(role.obtainLoginUserName());
					relation.setUpdatedBy(role.obtainLoginUserName());
					delList.add(relation);
				}
			}
			if(CollectionUtils.isNotEmpty(insertList)){
				n += sysRoleDao.insertNewRoleMenuRelations(insertList);
			}
			if(CollectionUtils.isNotEmpty(delList)){
				n += sysRoleDao.deleteRoleMenuRelations(delList);
			}
		}
		return n;
	}

	@Override
	public List<SysRoleDTO> getSysRolesByRoleCodes(List<String> roleCodes) throws MarvelsBusinessException {
		//通过查询的roleCodes查询角色，并级联用户
//		List<String> roleCodes = record.getQueryRoleCodes();
		if(roleCodes==null || roleCodes.size()<1){
			throw new MarvelsBusinessException("查询的角色不能为空");
		}
		List<SysRoleDTO> resultRoleDtos = new ArrayList();
		for(String roleCode:roleCodes){
			SysRoleDTO dto = new SysRoleDTO();
			dto.setRoleCode(roleCode.trim());
			//通过code查询角色
			Page<SysRoleDTO> resultDto = this.sysRoleDao.selectRolePage(dto);
			if(resultDto!=null && resultDto.size()>0){
				SysRoleDTO oneRole = resultDto.get(0);
				//查询用户
				List<SysUserDTO> users = getSysUsersByRole(oneRole);
				oneRole.setSysUsers(users);
				resultRoleDtos.add(oneRole);
			}
		}
		return resultRoleDtos;
	}
	
	public List<SysRoleDTO> getAllSysRolesByRoleCodes(List<String> roleCodes) throws MarvelsBusinessException {
		//通过查询的roleCodes查询角色，并级联用户
		List<SysRoleDTO> roleList = sysRoleDao.selectAll();
//		List<String> roleCodes = record.getQueryRoleCodes();
		if(roleCodes==null || roleCodes.size()<1){
			throw new MarvelsBusinessException("查询的角色不能为空");
		}
		List<SysRoleDTO> resultRoleDtos = new ArrayList();
		for(SysRoleDTO roleCode:roleList){
			SysRoleDTO dto = new SysRoleDTO();
			dto.setRoleCode(roleCode.getRoleCode().trim());
			//通过code查询角色
			Page<SysRoleDTO> resultDto = this.sysRoleDao.selectRolePage(dto);
			if(resultDto!=null && resultDto.size()>0){
				SysRoleDTO oneRole = resultDto.get(0);
				//查询用户
				List<SysUserDTO> users = getSysUsersByRole(oneRole);
				oneRole.setSysUsers(users);
				resultRoleDtos.add(oneRole);
			}
		}
		return resultRoleDtos;
	}
	
	//通过roleCode查询用户
	private List<SysUserDTO> getSysUsersByRole(SysRoleDTO roleDto){
		SysRoleDTO newDto = new SysRoleDTO();
		newDto.setRoleCode(roleDto.getRoleCode());
		String ignoreUserCodes= ServerProperties.getValue(configPropertiesPath, "common.properties", "ignore_user_code");
		if(StrUtil.isNotEmpty(ignoreUserCodes)){
			newDto.setIgnoreUserCodeList(Arrays.asList(ignoreUserCodes.split(",")));
		}
		List<SysUserDTO> sysUsers = sysUserDao.selectUserByRoleCode(newDto);
		return sysUsers;
	}
}
